package com.adxon.data;

import com.adxon.MsgException;
import com.adxon.servlet.ServletBase;
import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.KeyRange;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import javax.servlet.http.HttpServletRequest;

public class Base{
	protected final static Entity entity(String baseKind,long id)
			throws MsgException{
		Entity r=DatastoreServiceFactory.getDatastoreService().prepare(
				new Query(baseKind).setFilter(
				new FilterPredicate("id",FilterOperator.EQUAL,id))).
				asSingleEntity();
		if(r==null)
			throw new MsgException(MsgException.NOT_FOUND,null);
		return r;
	}
	protected final static Entity entity(String baseKind,String permaLink)
			throws MsgException{
		try{
			return DatastoreServiceFactory.getDatastoreService().get(
					KeyFactory.createKey(baseKind,permaLink));
		}catch(EntityNotFoundException e){
			throw new MsgException(MsgException.NOT_FOUND,null);
		}
	}
	public final static String regulate(String string){
		if(string!=null){
			string=string.trim();
			if(string.length()==0)
				string=null;
		}
		return string;
	}

	protected String	bsk;	// base kind
	protected Entity	ent;
	protected long		id;		// id
	protected String	pk;		// permalink

	protected String allocateId()throws MsgException{
		KeyRange k=DatastoreServiceFactory.getDatastoreService().
				allocateIds("i",1);
		id=k.getStart().getId()+ServletBase.site;
		return Long.toString(id);
	}
	public void commit()throws MsgException{
		if(ent==null){
			if(id==0){
				String p=allocateId();
				if(pk==null)
					pk=p;
			}
			ent=new Entity(bsk,pk);
		}
		commitExt();
		DatastoreServiceFactory.getDatastoreService().put(ent);
	}
	protected void commit(String name,byte value){
		ent.setProperty(name,value);
	}
	protected boolean commit(String name,byte[] value){
		if(value==null)
			return false;
		ent.setProperty(name,new Blob(value));
		return true;
	}
	protected void commit(String name,int value){
		ent.setProperty(name,value);
	}
	protected void commit(String name,long value){
		ent.setProperty(name,value);
	}
	protected void commit(String name,String value){
		ent.setProperty(name,value);
	}
	protected void commitExt()throws MsgException{
		commit("id",id);
	}
	public boolean equals(Base base){
		return base.id==id;
	}
	public void getAll(HttpServletRequest req){
		req.setAttribute("i",this);
	}
	public long getId(){
		return id;
	}
	public void getInfo(HttpServletRequest req)throws MsgException{
		getAll(req);
		req.setAttribute("Page","info.jsp");
	}
	public void getPage(HttpServletRequest req)throws MsgException{
		getAll(req);
		req.setAttribute("Page","page.jsp");
	}
	public void getPost(HttpServletRequest req)throws MsgException{
		getAll(req);
		req.setAttribute("Page","post.jsp");
	}
	public String getPermaLink(){
		return pk;
	}
	public void reset(){
		id=0;
		pk=null;
		ent=null;
	}
	public void setAll(Base src){
		if(ent==null)
			ent=src.ent;
		id=src.id;
		pk=src.pk;
	}
	public void setAll(HttpServletRequest req)throws MsgException{
	}
	public void setId(Base base){
		id=base.id;
	}
	public void setId(long value){
		id=value;
	}
	public void setPermaLink(long permaLink) {
		pk=Long.toString(permaLink);
	}
	public void setPermaLink(String permaLink){
		pk=permaLink;
	}
	@Override
	public String toString(){
		return Long.toString(id);
	}
	public Base update()throws MsgException{
		if(ent==null)
			ent=pk==null?entity(bsk,id):entity(bsk,pk);
		pk=(String)ent.getKey().getName();
		id=updateLong("id");
		return this;
	}
	public Base update(Entity entity)throws MsgException{
		ent=entity;
		return update();
	}
	public Base update(long id)throws MsgException{
		return update(entity(bsk,id));
	}
	public Base update(String permaLink)throws MsgException{
		update(entity(bsk,permaLink));
		return this;
	}
	protected Blob updateBlob(String name){
		return (Blob)ent.getProperty(name);
	}
	protected byte updateByte(String name){
		return ((Long)ent.getProperty(name)).byteValue();
	}
	protected int updateInt(String name){
		return ((Long)ent.getProperty(name)).intValue();
	}
	protected long updateLong(String name){
		return (Long)ent.getProperty(name);
	}
	protected String updateString(String name){
		return (String)ent.getProperty(name);
	}
}